import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.PrintWriter;


public class Stock {

	public Stock()
	{
		
	}
	
	public void Transform(String fileName, String IV, LargeKey partKey, int blockSize)
	{		
		byte[] bytesStock, bytesIV, bytesTemp;
		byte temp;
		int i, j;
		char fromStock, afterXor;
		
		try {
			File fStock = new File(fileName);
			FileInputStream inputStock = new FileInputStream(fStock);
			
			File fIV = new File(IV);
			FileInputStream inputIV = new FileInputStream(IV);
			
			FileWriter fwTransform = new FileWriter("Tranform.txt");
			PrintWriter pwTransform = new PrintWriter(fwTransform);
			
			bytesStock = new byte[(int)fStock.length()];
			inputStock.read(bytesStock);
			bytesIV = new byte[(int)fIV.length()];
			inputIV.read(bytesIV);
			
			//System.out.println("This is len for Stock = " + bytesStock.length);
			//System.out.println("This is len for IV = " + bytesIV.length);
			
			bytesTemp = new byte[blockSize + bytesStock.length];			
			for(i = 0; i < blockSize; i++)
				bytesTemp[i] = bytesIV[i];
			for(i = 0, j = blockSize; i < bytesStock.length; i++, j++)
				bytesTemp[j] = bytesStock[i];
			
			for(i = blockSize; i < bytesStock.length; i++)
			{
				fromStock = (char)bytesTemp[i];
				if(((fromStock >= 'a' && fromStock <= 'z') || (fromStock >= 'A' && fromStock <= 'Z')) && partKey.Mapped(fromStock))		
				{
					temp = (byte)partKey.GetValue(fromStock, "cipher");
					afterXor = (char)(bytesTemp[i - blockSize] ^ temp);
				}
				else				
					afterXor = (char)(bytesTemp[i - blockSize] ^ bytesTemp[i]);				
				pwTransform.write(afterXor);				
			}
			
			inputStock.close();
			inputIV.close();
			fwTransform.close();
			pwTransform.close();
		} 
		catch (Exception e)
		{
			e.printStackTrace();
			System.exit(1);
		}	
		
		
	}
	
	public String improvedTransform(byte[] cipher, LargeKey partKey, int blockSize)
	{		
		char[] res = new char[cipher.length-blockSize];
		byte temp;
		int i, j=0;
		char fromStock, afterXor;
		int len = cipher.length;
		
	
		for(i = blockSize; i < len; i++)
		{
			fromStock = (char)cipher[i];
			if(((fromStock >= 'a' && fromStock <= 'z') || (fromStock >= 'A' && fromStock <= 'Z')) && partKey.Mapped(fromStock))		
			{
				temp = (byte)partKey.GetValue(fromStock, "cipher");
				afterXor = (char)(cipher[i - blockSize] ^ temp);
			}
			else				
				afterXor = (char)(cipher[i - blockSize] ^ cipher[i]);				
			res[j]=afterXor;
			j++;
		}
		
		return new String(res);		
	}
}
